<?php

declare(strict_types=1);

namespace App\Middleware;

use Hyperf\Utils\Context;
use Psr\Container\ContainerInterface;
use Hyperf\Contract\ConfigInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class CorsMiddleware implements MiddlewareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var ConfigInterface
     */
    private $config;


    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->config = $container->get(ConfigInterface::class);
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $corsAccess = $this->config->get('cors_access');
        if ($corsAccess === true) {
            $origins = $this->config->get('allow_origins');
            $origin = $request->getHeader('origin');
            $origin = $origin?$origin[0]:false;
            
            if ($origin != false) {
                $isPort = (int)strripos($origin,':',5);
                if ($isPort) {
                    $ifOrigin = in_array(substr($origin,0,$isPort),$origins);
                } else {
                    $ifOrigin = in_array($origin,$origins);
                }
                if ( $ifOrigin ) {
                    
                    $response = Context::get(ResponseInterface::class);
                    $response = $response->withHeader('Access-Control-Allow-Origin', "{$origin}");
                    $response = $response->withHeader('Access-Control-Allow-Credentials', 'true');
                    $response = $response->withHeader('Access-Control-Allow-Headers', 'DNT,Keep-Alive,User-Agent,Cache-Control,Content-Type,HYPERF-SESSION-ID,UNI-TOKEN-ID');
                    Context::set(ResponseInterface::class, $response);
                    // 非简单跨域请求的"预检"请求处理
                    if ($request->getMethod() == 'OPTIONS') {
                        return $response;
                    }
                }
            }
        }
        return $handler->handle($request);
    }
}
